/**
 * @file nd03b_data.c
 * @author tongsheng.tang
 * @brief ND03B get depth data functions
 * @version 1.x.x
 * @date 2021-11
 * 
 * @copyright Copyright (c) 2021, Shenzhen Nephotonics Inc.
 * 
 */

#include "nd03b_comm.h"
#include "nd03b_dev.h"
#include "nd03b_data.h"
#include "nd03b_calib.h"

/**
 * @brief ND03B Wait Depth And Amp Buf Ready 
 *        等待ND03B测距完成
 * @param   pNxDevice 模组设备
 * @return  int32_t  
 * @retval  函数执行结果
 * - 0：正常返回
 * - ::ND03B_ERROR_TIME_OUT:获取数据超时
 */
int32_t ND03B_WaitDepthAndAmpBufReady(ND03B_Dev_t *pNxDevice)
{
    int32_t     ret = ND03B_ERROR_NONE;
    uint32_t    buf_valid_flag = 0x0;
    uint32_t    i = 1000;


    ND03B_Delay1ms(1);
    while(i)
    {
        ret |= ND03B_ReadWord(pNxDevice, ND03B_REG_DATA_VAL_REQ, &buf_valid_flag);
        // NX_PRINTF("%s -> buf_valid_flag2: 0x%08x\r\n", __func__, buf_valid_flag);
        if(ND03B_DEPTH_DATA_VAL_MASK == (buf_valid_flag & ND03B_DEPTH_DATA_VAL_MASK))
            break;
        ND03B_Delay10us(50);
        i--;
    }

    if(i == 0)
    {
        return ND03B_ERROR_TIME_OUT;
    }

    return ret;
}

/**
 * @brief ND03B Start Measurement 
 *        发送开始测量信号
 * @param   pNxDevice 模组设备
 * @return  int32_t   
 */
int32_t ND03B_StartMeasurement(ND03B_Dev_t *pNxDevice)
{
    int32_t     ret = ND03B_ERROR_NONE;

    //Set data_req
    ret |= ND03B_WriteWord(pNxDevice, ND03B_REG_DATA_VAL_REQ, ND03B_DEPTH_DATA_REQ_MASK); //发送触发信号

    return ret;
}

/**
 * @brief ND03B Stop Measurement 
 *        发送结束测量信号，用于连续模式
 * @param   pNxDevice 模组设备
 * @return  int32_t   
 */
int32_t ND03B_StopMeasurement(ND03B_Dev_t *pNxDevice)
{
    int32_t     ret = ND03B_ERROR_NONE;
    uint32_t    data_req_flag = 0x0;

    ret |= ND03B_ReadWord(pNxDevice, ND03B_REG_DATA_VAL_REQ, &data_req_flag);
    data_req_flag = data_req_flag & (~ND03B_DEPTH_DATA_REQ_MASK);
    ret |= ND03B_WriteWord(pNxDevice, ND03B_REG_DATA_VAL_REQ, data_req_flag);

    return ret;
}

/**
 * @brief ND03B Read Depth And Amp Data 
 *        读取ND03B寄存器获取深度幅度数据，数据更新于一次测距完成后
 * @param   pNxDevice 模组设备
 * @param   pData  获取到的深度和幅度数据
 * @return  int32_t   
 */
int32_t ND03B_ReadDepthAndAmpData(ND03B_Dev_t *pNxDevice, ND03B_RangingData_t *pData)
{
    int32_t     ret = ND03B_ERROR_NONE;
    uint32_t    rbuf;
    uint32_t    depth;
    uint32_t    amp;

    ret |= ND03B_ReadWord(pNxDevice, ND03B_REG_AMP_DEPTH, &rbuf);
    amp = rbuf >> 16;
    depth = rbuf & 0xFFFF;

    pData->amp = amp;
    pData->depth = amp < 30 ? ND03B_DEPTH_LOW_AMP : depth;  // 幅度值过低

    return ret;
}

/**
 * @brief ND03B Clear Data Valid Flag 
 *        清除ND03B测量数据的有效位，取完一次数
 *        据做的操作，通知ND03B数据已读取
 * @param   pNxDevice 模组设备
 * @return  int32_t   
 */
int32_t ND03B_ClearDataValidFlag(ND03B_Dev_t *pNxDevice)
{
    int32_t     ret = ND03B_ERROR_NONE;
    uint32_t    data_valid_flag = 0;
    
    ret |= ND03B_ReadWord(pNxDevice, ND03B_REG_DATA_VAL_REQ, &data_valid_flag);
    data_valid_flag = data_valid_flag & (~ND03B_DEPTH_DATA_VAL_MASK);
    ret |= ND03B_WriteWord(pNxDevice, ND03B_REG_DATA_VAL_REQ, data_valid_flag);

    return ret;
}

/**
 * @brief ND03B Get Ranging Data 
 *        从ND03B中获取一次深度数据，
 *        需要与ND03B_StartMeasurement函数搭配
 * @param   pNxDevice 模组设备
 * @param   pData  获取到的深度和幅度数据
 * @return  int32_t   
 */
int32_t ND03B_GetRangingData(ND03B_Dev_t *pNxDevice, ND03B_RangingData_t *pData)
{
    int32_t     ret = ND03B_ERROR_NONE;

    /* 读取测量数据 */
    ret |= ND03B_ReadDepthAndAmpData(pNxDevice, pData);
    /* 休眠 */
    ret |= ND03B_Sleep(pNxDevice);

    return ret;
}
